package misc;

import java.io.PrintStream;


public class Log {

	private static final class Holder extends ThreadLocal<Log> {
		@Override
		protected Log initialValue() {
			return new Log();
		}
	}

	private static final Holder holder = new Holder();
	
	public static final int NO_DEBUG = 0, NO_INFO = 1, NO_WARNING = 2, NO_ERROR = 3, NO_FATAL = 4;
	
	private static final String[] DESCRIPTION = {"DEBUG","INFO","WARNING","ERROR","FATAL"};
	private static final PrintStream[] STREAM = {System.out,System.out,System.out,System.err,System.err};
	private static final boolean EXIT[] = {false,false,false,false,true};
	
	private boolean[] active = {true,true,true,true,true};
	private String name = "UNKNOWN";

	private Log(){}
	
	public static void init(String name, int... deactivate){
		Log log = holder.get();
		log.name = name;
		for(int d : deactivate){
			log.active[d] = false;
		}
	}
	
	public static void debug(String msg){
		print(msg,Log.NO_DEBUG);
	}
	
	public static void info(String msg){
		print(msg,Log.NO_INFO);
	}
	
	public static void warning(String msg){
		print(msg,Log.NO_WARNING);
	}
	
	public static void error(String msg){
		print(msg,Log.NO_ERROR);
	}
	
	public static void fatal(String msg){
		print(msg,Log.NO_FATAL);
	}
	
	private static synchronized void print(String msg, int level){
		Log log = holder.get();
		if(log.active[level]){
			STREAM[level].println("Thread:"+log.name+" "+DESCRIPTION[level]+":\t"+msg);
			if(EXIT[level]) System.exit(1);
		}
	}
	
}
